#include <iostream>

using namespace std;

// 多态条件
// 1、调用函数是重写的虚函数
// 2、基类指针或者引用

//class Person {
//public:
//	virtual	void BuyTicket() const { 
//		cout << "买票-全价" << endl;
//	}
//};
//
//class Student : public Person {
//public:
//	//建议写上virtual
//	 virtual void BuyTicket() const { 
//		cout << "买票-半价" << endl;
//	}
//};
//
//void func(const Person& p)
//{
//	p.BuyTicket();
//}
//
//int main()
//{
//	func(Person());
//
//	func(Student());
//
//	return 0;
//}

//class A 
//{};
//
//class B : public A 
//{};
//
//class Person {
//public:
//	virtual A* f() 
//	{ 
//		return new A; 
//	}
//};
//class Student : public Person {
//public:
//	virtual B* f() 
//	{
//		return new B; 
//	}
//};

//class Person {
//public:
//	virtual ~Person() 
//	{
//		cout << "~Person()" << endl; 
//	}
//};
//class Student : public Person {
//public:
//	//建议派生类也写上virtual
//	virtual ~Student() 
//	{
//		cout << "~Student()" << endl; 
//	}
//};
//
//int main()
//{
//	Person* p = new Person;
//	delete p;
//
//	p = new Student;
//	delete p;
//
//	return 0;
//}

//class Person {
//public:
//	virtual ~Person  () final
//	{
//		cout << "~Person()" << endl; 
//	}
//};
//class Student : public Person {
//public:
//	virtual ~Student() 
//	{
//		cout << "~Student()" << endl; 
//	}
//};

//class Car {
//public:
//	void Drive() {}
//};
//class Benz :public Car {
//public:
//	virtual void Drive() override 
//	{
//		cout << "BYD-舒适" << endl; 
//	}
//};


//final修饰的类不能被继承
//class A final
//{};
//
//class B : public A
//{};
//
//int main()
//{
//	return 0;
//}

//class A
//{
//public:
//	static A GetInst()
//	{
//		return A();
//	}
//private:
//	A()
//	{}
//};
//
//class B : public A
//{};
//
//int main()
//{
//	A a = A::GetInst();
//	B bb;
//	return 0;
//}


////sizeof(Base)是多少？
//class Base
//{
//public:
//	virtual void Func1()
//	{
//		cout << "Func1()" << endl;
//	}
//private:
//	char _b = 1;
//};
//	
//int main()
//{
//	cout << sizeof(Base) << endl;
//	
//	Base b1;
//	
//	return 0;
//}


//class Person {
//public:
//	virtual void BuyTicket() { cout << "买票-全价" << endl; }
//
//	int _a = 1;
//};
//
//class Student : public Person {
//public:
//	virtual void BuyTicket() { cout << "买票-半价" << endl; }
//	int _b = 1;
//};
//
//void Func(Person p)
//{
//	// 不符合多态，编译时确认函数地址
//	p.BuyTicket();
//}
//
//int main()
//{
//	Person Mike;
//	Func(Mike);
//
//	Student Johnson;
//	Func(Johnson);
//
//	return 0;
//}

//输出结果什么呢？
//class A
//{
//public:
//    virtual void func(int val = 1) { std::cout << "A->" << val << std::endl; }
//    virtual void test(){func();}
//};
//
//class B : public A
//{
//public:
//    void func(int val = 0) { std::cout << "B->" << val << std::endl; }
//
//};
//
//int main(int argc, char* argv[])
//{
//    B* p = new B;
//    p->test();
//    return 0;
//}

//class Person {
//public:
//	virtual void BuyTicket() { cout << "买票-全价" << endl; }
//
//	virtual void Func1() 
//	{
//		cout << "Person::Func1()" << endl;
//	}
//
//	virtual void Func2() 
//	{
//		cout << "Person::Func2()" << endl;
//	}
//
////protected:
//	int _a = 0;
//};
//
//class Student : public Person {
//public:
//	virtual void BuyTicket() { cout << "买票-半价" << endl; }
//	virtual void Func3()
//	{
//		cout << "Student::Func3()" << endl;
//
//	}
//private:
//protected:
//	int _b = 1;
//};
//
////重命名一下函数指针类型
//typedef void(*FUNC_PTR) ();
//
//// 打印函数指针数组
//// void PrintVFT(FUNC_PTR table[])
//void PrintVFT(FUNC_PTR* table)
//{
//	//vs平台下，虚函数表结尾都是nullptr
//	for (size_t i = 0; table[i] != nullptr; i++)
//	{
//		printf("[%d]:%p->", i, table[i]);
//
//		FUNC_PTR f = table[i];
//		f();
//	}
//	printf("\n");
//}
//
//int main()
//{
//	Person ps;
//	Student st;
//
//	//根据内存窗口可以看到，多态类的虚函数表存在类对象前4字节中
//	int vft1 = *((int*)&ps);
//	PrintVFT((FUNC_PTR*)vft1);
//
//	int vft2 = *((int*)&st);
//	PrintVFT((FUNC_PTR*)vft2);
//
//	return 0;
//}




//int main()
//{
//	Person mike;
//	Student jack;
//
//	mike = jack;
//
//	return 0;
//}
//
//int main()
//{
//	Person ps;
//	Student st;
//
//	int a = 0;
//	printf("栈：%p\n", &a);
//
//	static int b = 0;
//	printf("静态区：%p\n", &b);
//
//	int* p = new int;
//	printf("堆：%p\n", p);
//
//	const char* str = "hello world";
//	printf("常量区：%p\n", str);
//
//	printf("虚表1：%p\n", *((int*)&ps));
//	printf("虚表2：%p\n", *((int*)&st));
//
//
//	return 0;
//}


//int main()
//{
//	int a = 10;
//	double b = 3.14;
//
//	//静态时多态
//	cout << a << endl;
//	cout << b << endl;
//
//	Person ps;
//	Person* ptr = &ps;
//
//	//普通调用
//	ps.BuyTicket();
//
//	//多态调用
//	ptr->BuyTicket();
//
//	return 0;
//}

//class Base1 {
//public:
//	virtual void func1() { cout << "Base1::func1" << endl; }
//	virtual void func2() { cout << "Base1::func2" << endl; }
//private:
//	int b1;
//};
//
//class Base2 {
//public:
//	virtual void func1() { cout << "Base2::func1" << endl; }
//	virtual void func2() { cout << "Base2::func2" << endl; }
//private:
//	int b2;
//};
//
//class Derive : public Base1, public Base2 {
//public:
//	virtual void func1() { cout << "Derive::func1" << endl; }
//	virtual void func3() { cout << "Derive::func3" << endl; }
//private:
//	int d1;
//};
//
//int main()
//{
//	Derive d;
//	Base1* ptr1 = &d;
//	ptr1->func1();
//
//	Base2* ptr2 = &d;
//	ptr2->func1();
//
//	Derive* ptr3 = &d;
//	ptr3->func1();
//
//	return 0;
//}

//class Car
//{
//public:
//	virtual void Drive() = 0;
//};
//class Benz :public Car
//{
//public:
//	virtual void Drive()
//	{
//		cout << "Benz-舒适" << endl;
//	}
//};
//class BMW :public Car
//{
//public:
//	//virtual void Drive()
//	//{
//	//	cout << "BMW-操控" << endl;
//	//}
//};
//
////强制派生类虚函数重写
//void Func(Car* pc)
//{
//	pc->Drive();
//}
//
//int main()
//{
//	Benz B;
//	return 0;
//}

//class Car
//{
//public:
//	virtual void Drive() = 0;
//};
//class Benz :public Car
//{
//public:
//	//virtual void Drive()
//	//{
//	//	cout << "Benz-舒适" << endl;
//	//}
//};
//class BMW :public Car
//{
//public:
//	//virtual void Drive()
//	//{
//	//	cout << "BMW-操控" << endl;
//	//}
//};
//
//int main()
//{
//	BMW b;
//	return 0;
//}

class A
{
public:
	virtual void func1()
	{
		cout << "A::func1" << endl;
	}
public:
	int _a;
};

//class B : public A
class B : virtual public A
{
public:
	virtual void func1()
	{
		cout << "B::func1" << endl;
	}

	virtual void func2()
	{
		cout << "B::func2" << endl;
	}
public:
	int _b;
};

//class C : public A
class C : virtual public A
{
public:
	virtual void func1()
	{
		cout << "C::func1" << endl;
	}

	virtual void func2()
	{
		cout << "C::func2" << endl;
	}
public:
	int _c;
};

class D : public B, public C
{
public:
	virtual void func1()
	{
		cout << "D::func1" << endl;
	}

	virtual void func3()
	{
		cout << "D::func3" << endl;
	}
public:
	int _d;
};

int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;

	return 0;
}